
// ES6 实现方式

// 有三种状态 成功(fulfilled) 失败(rejected) 等待(pending)。
let PENDING='pending'
let REJECTED='rejected'
let FULFILLED='fulfilled'
class MyPromise{
    constructor(executor){
        // console.log(executor,'========')
        executor(this.resolve,this.reject)
    }

    // 声明状态
    status = PENDING;
    // 传递的参数，分为成功和失败
    value = undefined;  // 成功
    reason = undefined  // 失败

    // 成功和失败的回调存储起来，等到异步的的时候调用

    // 单个then的时候可以使用
    // successCallback = undefined   
    // failCallback = undefined     

    // 因为then是可以多次调用的，多个then的时候需要把每次的回调都需要存储起来
    successCallback = []
    failCallback = []
    // resolve 方法的实现
    resolve= value =>{
        if(this.status !== PENDING) return
        this.status = FULFILLED
        this.value = value

        //也就是说this.value的值已经有了，但是then,没有执行到，就需要把value的是收集起来，同意给then方法操作
        // console.log(this.value)
        // this.successCallback && this.successCallback(this.value)
        while(this.successCallback.length){
            this.successCallback.shift()(this.value)
        }
    }
    reject= reason =>{
        if(this.status !== PENDING) return
        this.status = REJECTED
        this.reason = reason

        // this.failCallback && this.failCallback(this.reason)
        while(this.failCallback.length){
            this.failCallback.shift()(this.reason)
        }
    }
    // then的实现，then 有两个参数，一个成功回调，一个失败回调
    then(successCallback,failCallback) {
        // 状态判断
        // if(this.status === FULFILLED) {
        //     successCallback(this.value)
        // }else if(this.status === REJECTED) {
        //     failCallback(this.reason)
        // }else{
        //     // console.log(this.value)
        //     // 把成功和失败的回调存储起来
        //     this.successCallback.push(successCallback)
        //     this.failCallback.push(failCallback)
        // }
        

        // then 可以链式调用，就需要当前的then拿到之前上一个then的返回值，

        let promise2 = new MyPromise((resolve,reject)=>{
            console.log(this.value,this.reason,'=========')
            // 同上，先状态判断
            if(this.status === FULFILLED){
                // 把then的值存起来，通过resove()，传递到下一个then的方法
                let x = successCallback(this.value)
                //then是可以接受一个promise对象的，需要判断x 返回的是一个Promise对象
                // resolve(x)
                setTimeout(()=>{ // 使用异步未0，避免在promise2中拿到自身的返回
                    resolvePromise(promise2,x,resolve,reject)
                },0)
            }else if(this.status === REJECTED){
                // 失败原因不需要传递,只需要报错出来就行
                failCallback(this.reason)
            }else{
                this.successCallback.push(successCallback)
                this.failCallback.push(failCallback)
            }
        })
        return promise2
    }
}

//通过resolvePromise判断返回值的是promise对象还是普通值
function resolvePromise(promise2, x, resolve, reject){
    console.log(x,'==========')
    if(promise2 === x){
        return reject(new TypeError('Chaning cycle deteced for prmise #<Promise>'))
    }
    if(x instanceof MyPromise){
        // x.then((value)=>resolve(value),(reason)=>reject(reason))
        // 简写
        x.then(resolve,reject)
    }else{
        resolve(x)  // 普通值
    }
}

module.exports = MyPromise